package openbang.chatroom.service.impl;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.logging.Logger;

import com.google.gwt.user.server.rpc.RemoteServiceServlet;

import openbang.chatroom.service.intf.ChatService;
import openbang.chatroom.service.util.CacheHelper;
import openbang.chatroom.service.util.DateTimeHelper;
import openbang.chatroom.service.vo.CacheKeyDefine;
import openbang.chatroom.service.vo.ChatGroup;
import openbang.chatroom.service.vo.ChatGroupMsg;
import openbang.chatroom.service.vo.ChatMsg;
import openbang.chatroom.service.vo.ChatServiceEnum;

/**
 * 聊天服务
 * 不必登录
 * 使用  GAE 提供的 Memcache实现消息的缓存
 * GAE的缓存不支持从缓存中获取所有值(或键值 ),所以要应用程序自己保存？List<String> AllGroupId
 * 
 * 会有多台应用服务器
 * 
 * @author aibo zeng
 *
 */

@SuppressWarnings("serial")
public class ChatServiceImpl  extends RemoteServiceServlet implements ChatService{
	private static final Logger log = Logger.getLogger(ChatServiceImpl.class.getName());
    private static int MaxGroupNum = 50;   //存在的最大总数
    
	@Override
	public String createGroup(ChatGroup chatGroup) {
		log.warning("createGroup "+chatGroup.getSubject());		
		if(CacheHelper.getChatGroupAll().size()>=MaxGroupNum){
			return "ER"+ChatServiceEnum.OVER_NUM.getCode();
		}
		//判断缓存中是否存在
		//if(getCache().containsKey(chatGroup.getGroupId())){
		//	return ChatServiceEnum.EXIST_GROUP.getCode();
		//}
		//创建
		ChatGroupMsg gm = new ChatGroupMsg();
		gm.setCreator(getThreadLocalRequest().getSession(true).getId());//session id 记录同一个游客创建的群
		gm.setNiceName(chatGroup.getNiceName());
		gm.setGroupId(CacheKeyDefine.CHATGROUP_PREFIX+DateTimeHelper.getUniqueId());
		gm.setPassword(chatGroup.getPassword());
		gm.setSubject(chatGroup.getSubject());
		gm.addParticipant(chatGroup.getNiceName());
		//放入缓存
		CacheHelper.add(gm.getGroupId(),gm);
		return "OK"+gm.getGroupId();
	}

	@Override
	public Integer deleteGroup(String groupId) {
		log.warning("deleteGroup "+groupId);
		CacheHelper.remove(groupId);
		return ChatServiceEnum.OK.getCode();
	}

	@Override
	public List<ChatGroup> getAllGroup() {
		List<ChatGroup> chatGroups = new ArrayList<ChatGroup>();
		HashSet allGroup =  CacheHelper.getChatGroupAll();
		if(!allGroup.isEmpty()){
			Iterator iterator = allGroup.iterator();
			while(iterator.hasNext()){
				ChatGroupMsg gm = (ChatGroupMsg)CacheHelper.get((String)iterator.next());
				ChatGroup cg = new ChatGroup();
				cg.setCreator(gm.getCreator());
				cg.setGroupId(gm.getGroupId());
				cg.setPassword(gm.getPassword());
				cg.setSubject(gm.getSubject());
				cg.setNiceName(gm.getNiceName());
				cg.setCreateDate(gm.getCreateDate());
				chatGroups.add(cg);
			}
		}
		return chatGroups;
	}

	@Override
	public Integer joinGroup(String groupId , String participant , String password) {
		log.warning("joinGroup "+groupId +",participant="+participant);
		ChatGroupMsg gm = (ChatGroupMsg)CacheHelper.get(groupId);
		//判断缓存中是否存在
		if(gm==null){
			return ChatServiceEnum.NOEXIST_GROUP.getCode();
		}
		if(gm.getPassword().equals(password)){
			if(gm.addParticipant(participant)){
			    CacheHelper.put(groupId, gm);
			}
			return ChatServiceEnum.OK.getCode();
		}
		else{
			return ChatServiceEnum.ERR_PWD.getCode();
		}
	}

	@Override
	public Integer quitGroup(String groupId , String participant) {
		log.warning("quitGroup "+groupId +",participant="+participant);
		ChatGroupMsg gm = (ChatGroupMsg)CacheHelper.get(groupId);
		//判断缓存中是否存在
		if(gm==null){
			return ChatServiceEnum.OK.getCode();
		}
		boolean changed = gm.removeParticipant(participant);
		if(gm.isParticipantEmpty()){
			CacheHelper.remove(groupId);
			log.info("remove Group  from cache "+groupId);
		}
		else{
			if(changed){
			   //有变化,需要重置缓存
			   CacheHelper.put(groupId, gm);
			}
		}
		return ChatServiceEnum.OK.getCode();
	}

	@Override
	public ChatGroup getChatGroup(String groupId) {
		ChatGroup cg = new ChatGroup();
		ChatGroupMsg gm = (ChatGroupMsg)CacheHelper.get(groupId);
		if(gm!=null){
			cg.setCreateDate(gm.getCreateDate());
			cg.setCreator(gm.getCreator());
			cg.setGroupId(gm.getGroupId());
			cg.setNiceName(gm.getNiceName());
			cg.setPassword(gm.getPassword());
			cg.setSubject(gm.getSubject());
			//不含 cg.setParticipants(gm.getParticipants());
		}
		return cg;
	}

	@Override
	public List<ChatMsg> getNewChatMsg(String groupId, String token,
			String participant) {
		log.warning("getNewChatMsg participant="+participant+", token="+token);
		List<ChatMsg> retMsg = new ArrayList<ChatMsg>();
		long tokenLong = Long.parseLong(token);
		ChatGroupMsg gm = (ChatGroupMsg)CacheHelper.get(groupId);
		if(gm!=null){
			List<ChatMsg> haveMsgs = gm.getChatMsgs();
			for(ChatMsg cm : haveMsgs){
				if( Long.parseLong(cm.getToken()) <= tokenLong ){
					continue;
				}
				if(cm.getSender().equals(participant)){
					continue;
				}
				retMsg.add(cm);
			}
		}
		log.warning("getNewChatMsg size="+retMsg.size());
		return retMsg;
	}

	@Override
	public Integer sendMsg(String groupId, String participant , String msg) {
		log.warning("sendMsg participant="+participant);
		ChatGroupMsg gm = (ChatGroupMsg)CacheHelper.get(groupId);
		if(gm!=null){
			long token = gm.addNewMsg(participant, msg);
			CacheHelper.put(groupId, gm);
			log.warning("sendMsg ok , token = "+token);
			return ChatServiceEnum.OK.getCode();
		}
		else{
			return ChatServiceEnum.NOEXIST_GROUP.getCode();
		}
	}

	@Override
	public Set<String> getParticipants(String groupId) {
		ChatGroupMsg gm = (ChatGroupMsg)CacheHelper.get(groupId);
		if(gm!=null){
			return gm.getParticipants();
		}
		return null;
	}
}
